﻿using DotNetNuke.UI.Skins.Controls;
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by DotNetNuke Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using System.Web.UI;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using WebFormsMvp;
using DotNetNuke.UI.Modules;
using DotNetNuke.Web.Validators;
using DotNetNuke.Services.Localization;
using DotNetNuke.Entities.Modules;

namespace DotNetNuke.Web.Mvp
{

    public abstract class ModulePresenterBase<TView> : Presenter<TView> where TView : class, IModuleViewBase
    {

        #region "Private Members"

        private ModuleInfo _moduleInfo;
        private bool _IsEditable;
        private bool _IsPostBack;
        private bool _IsSuperUser;
        private string _LocalResourceFile;
        private ModuleInstanceContext _ModuleContext;
        private int _ModuleId;
        private int _PortalId;
        private Dictionary<string, string> _Settings;
        private int _TabId;
        private int _UserId;

        private Validator _Validator;
        #endregion

        #region "Constructors"

        public ModulePresenterBase(TView view)
            : base(view)
        {

            //Try and cast view to Control to get common control properties
            Control control = view as Control;
            if (control != null && control.Page != null)
            {
                _IsPostBack = control.Page.IsPostBack;
            }

            //Try and cast view to IModuleControl to get the Context
            IModuleControl moduleControl = view as IModuleControl;
            if (moduleControl != null)
            {
                _LocalResourceFile = moduleControl.LocalResourceFile;
                _ModuleContext = moduleControl.ModuleContext;
                LoadFromContext();
            }
            _Validator = new Validator(new DataAnnotationsObjectValidator());

            view.Initialize += InitializeInternal;
            view.Load += LoadInternal;
        }

        #endregion

        #region "Protected Properties"

        protected internal virtual bool AllowAnonymousAccess
        {
            get { return true; }
        }

        protected internal virtual bool IsUserAuthorized
        {
            get { return true; }
        }

        #endregion

        #region "Public Properties"

        public ModuleInfo ModuleInfo
        {
            get { return _moduleInfo; }
            set { _moduleInfo = value; }
        }

        public bool IsEditable
        {
            get { return _IsEditable; }
            set { _IsEditable = value; }
        }

        public bool IsPostBack
        {
            get { return _IsPostBack; }
            set { _IsPostBack = value; }
        }

        public bool IsSuperUser
        {
            get { return _IsSuperUser; }
            set { _IsSuperUser = value; }
        }

        public string LocalResourceFile
        {
            get { return _LocalResourceFile; }
            set { _LocalResourceFile = value; }
        }

        public ModuleInstanceContext ModuleContext
        {
            get { return _ModuleContext; }
            set { _ModuleContext = value; }
        }

        public int ModuleId
        {
            get { return _ModuleId; }
            set { _ModuleId = value; }
        }

        public int PortalId
        {
            get { return _PortalId; }
            set { _PortalId = value; }
        }

        public int TabId
        {
            get { return _TabId; }
            set { _TabId = value; }
        }

        public int UserId
        {
            get { return _UserId; }
            set { _UserId = value; }
        }

        public Dictionary<string, string> Settings
        {
            get { return _Settings; }
            set { _Settings = value; }
        }

        public Validator Validator
        {
            get { return _Validator; }
            set { _Validator = Validator; }
        }

        #endregion

        #region "Event Handlers"

        private void InitializeInternal(object sender, EventArgs e)
        {
            OnInit();
        }

        private void LoadInternal(object sender, EventArgs e)
        {
            if (CheckAuthPolicy())
            {
                OnLoad();
            }
        }

        #endregion

        #region "Protected Methods"

        protected internal virtual bool CheckAuthPolicy()
        {
            if ((UserId == Null.NullInteger && !AllowAnonymousAccess))
            {
                OnNoCurrentUser();
                return false;
            }

            if ((!IsUserAuthorized))
            {
                OnUnauthorizedUser();
                return false;
            }

            return true;
        }

        protected virtual void LoadFromContext()
		{
			if (ModuleContext != null) {
				ModuleInfo = ModuleContext.Configuration;
				IsEditable = ModuleContext.IsEditable;
				IsSuperUser = ModuleContext.PortalSettings.UserInfo.IsSuperUser;
				ModuleId = ModuleContext.ModuleId;
				PortalId = ModuleContext.PortalId;
				Settings = new Dictionary<string, string>();
				foreach (var key in ModuleContext.Settings.Keys) {
					Settings[key.ToString()] = (string)ModuleContext.Settings[key];
				}
				TabId = ModuleContext.TabId;
				UserId = ModuleContext.PortalSettings.UserInfo.UserID;
			}
		}

        protected virtual string LocalizeString(string key)
        {
            string localizedString = null;
            if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(LocalResourceFile))
            {
                localizedString = Localization.GetString(key, LocalResourceFile);
            }
            else
            {
                localizedString = Null.NullString;
            }
            return localizedString;
        }

        protected virtual void OnInit()
        {
        }

        protected virtual void OnLoad()
        {
        }

        protected virtual void OnNoCurrentUser()
        {
            RedirectToLogin();
        }

        protected virtual void OnUnauthorizedUser()
        {
            RedirectToAccessDenied();
        }

        protected void RedirectToAccessDenied()
        {
            Response.Redirect(Globals.AccessDeniedURL(), true);
        }

        protected void RedirectToLogin()
        {
            Response.Redirect(Globals.LoginURL(Request.RawUrl, false), true);
        }

        protected void ProcessModuleLoadException(Exception ex)
        {
            View.ProcessModuleLoadException(ex);
        }

        protected void ShowMessage(string messageHeader, string message, ModuleMessage.ModuleMessageType messageType)
        {
            ShowMessage(messageHeader, message, messageType, true);
        }

        protected void ShowMessage(string message, ModuleMessage.ModuleMessageType messageType)
        {
            ShowMessage(message, messageType, true);
        }

        protected void ShowMessage(string message, ModuleMessage.ModuleMessageType messageType, bool localize)
        {
            ShowMessage(string.Empty, message, messageType, localize);
        }

        protected void ShowMessage(string messageHeader, string message, ModuleMessage.ModuleMessageType messageType, bool localize)
        {
            if (!string.IsNullOrEmpty(message))
            {
                if (localize)
                {
                    messageHeader = LocalizeString(messageHeader);
                    message = LocalizeString(message);
                }
                View.ShowMessage(messageHeader, message, messageType);
            }
        }

        #endregion

        #region "Public Methods"

        public override void ReleaseView()
        {
        }

        public virtual void RestoreState(StateBag stateBag)
        {
            AttributeBasedViewStateSerializer.DeSerialize(this, stateBag);
        }

        public virtual void SaveState(StateBag stateBag)
        {
            AttributeBasedViewStateSerializer.Serialize(this, stateBag);
        }

        #endregion

    }

}
